package com.landinfo.repository;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.util.ResourceUtils;

import javax.persistence.Query;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 动态模板（动态表单、动态表）
 */
@Repository
public class DynamicTemplateRepository {

    private final Logger log = LoggerFactory.getLogger(DynamicTemplateRepository.class);
    private Configuration configuration = null;
    private SessionFactory _sessionFactory = null;

    public DynamicTemplateRepository() {

    }


    private synchronized SessionFactory getSessionFactory() {
        // 注释以下代码，否则数据库中的字段不会及时刷新
        //if (this.configuration == null) {
        //    this.configuration = new Configuration();
        //}
        if (this._sessionFactory == null) {
            this.configuration = new Configuration();
            this.configuration.configure();
            this.addResource();
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
            _sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            //_sessionFactory = configuration.buildSessionFactory();
        }
        return _sessionFactory;
    }

    /**
     * 设置sessionFactory为空
     */
    public void setSessionFactoryNull() {
        this._sessionFactory = null;
    }

    public void saveOrUpdate(String entityName, Object dynamicTemplateMap) {
        Session session = this.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        session.saveOrUpdate(entityName, dynamicTemplateMap);
        tx.commit();
        session.close();
    }

    /**
     * 创建模板（表单）
     *
     * @return
     */
    public String saveDynamicTable(String dynamicTemplateName, HashMap<String, Object> rows) {
        Transaction tx = null;
        Session session = null;
        try {
            session = getSessionFactory().openSession();
            tx = session.beginTransaction();
            session.merge(dynamicTemplateName, rows);
            //session.clear();
            //session.save(dynamicTemplateName, rows);
            session.flush();
            tx.commit();
            session.close();
            return null;
        } catch (Exception ex) {
            if (tx != null) {
                tx.rollback();
            }
            if (session != null) {
                session.close();
            }
            return ex.getLocalizedMessage();
        }

    }


    /**
     * 执行hql语句
     *
     * @param hql
     * @return
     */
    public Boolean createQueryUpate(String hql) {
        Session session = null;
        try {
            session = getSessionFactory().openSession();
            Transaction transaction = session.beginTransaction();
            Query query = session.createQuery(hql);
            query.executeUpdate();
            transaction.commit();
            session.close();
            return true;
        } catch (Exception ex) {
            if (session != null) {
                session.close();
            }
            return false;
        }
    }

    /**
     * 执行hql语句
     *
     * @param hql
     * @return
     */
    public Integer createQueryCount(String hql) {
        Session session = null;
        try {
            session = getSessionFactory().openSession();
            Integer count = ((Number) session.createQuery(hql).uniqueResult()).intValue();
            session.close();
            return count;
        } catch (Exception ex) {
            if (session != null) {
                session.close();
            }
            return null;
        }
    }

    /**
     * 执行hql语句
     *
     * @param hql
     * @return
     */
    public List createQueryList(String hql) {
        Session session = getSessionFactory().openSession();
        List list = session.createQuery(hql).list();
        session.close();
        return list;
    }

    /**
     * 执行hql语句,返回分页结果
     *
     * @param hql
     * @param pageIndex
     * @param pageSize
     * @return
     */
    public List createQueryList(String hql, Integer pageIndex, Integer pageSize) {
        Session session = getSessionFactory().openSession();
        Query query = session.createQuery(hql);
        if (pageIndex != null && pageSize != null) {
            query.setFirstResult((pageIndex - 1) * pageSize);
            query.setMaxResults(pageSize);
        }
        List list = query.getResultList();
        session.close();
        return list;
    }

    /**
     * 执行hql语句
     *
     * @param hql
     * @return
     */
    public List createSqlQueryList(String hql) {
        Session session = getSessionFactory().openSession();
        List list = session.createNativeQuery(hql).list();
        session.close();
        return list;
    }

    /**
     * /**
     * 执行hql语句
     *
     * @param hql
     * @return
     */
    public Object createQueryObject(String hql) {
        Session session = getSessionFactory().openSession();
        Object object = session.createQuery(hql).uniqueResult();    //.list();
        session.close();
        return object;
    }

    /**
     * 根据对象名，id获取对象
     *
     * @param entityName
     * @param id
     * @return
     */
    public Object get(String entityName, String id) {
        Session session = getSessionFactory().openSession();
        Object dynamicTemplate = session.get(entityName, id);
        session.close();
        return dynamicTemplate;
    }


    /**
     * 执行hql语句
     *
     * @param hql
     * @return
     */
    public List createQueryListTopN(String hql, Integer topN) {
        Session session = getSessionFactory().openSession();
        Query query = session.createQuery(hql);
        query.setMaxResults(topN);
        List list = query.getResultList();
        session.close();
        return list;
    }


    public String getDynamicTable(String entityName) {

        Session session = getSessionFactory().openSession();
        String hql = String.format("from %s ORDER BY createDateTime desc", entityName);
        List<Object> dynamicTable = session.createQuery(hql).list();
        String result = null;
        if (dynamicTable != null) {
            //result = JSON.toJSONString(dynamicTable);
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
            result = gson.toJson(dynamicTable);
        }
        session.close();
        return result;
    }

    public String getDynamicTable(String entityName, String where) {

        Session session = getSessionFactory().openSession();
        String hql = String.format("from %s where %s", entityName, where);
        List<Object> dynamicTable = session.createQuery(hql).list();
        String result = null;
        if (dynamicTable != null) {
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
            result = gson.toJson(dynamicTable);
//            result = JSON.toJSONString(dynamicTable);
        }
        session.close();
        return result;
    }


    public boolean delDynamicFromDatabase(String parentId) {
        try {
            Session session = this.getSessionFactory().openSession();
            Transaction tx = session.beginTransaction();
            String delHql = String.format("delete %s a where a.parentId='%s'", "DynamicTemplateChild", parentId);
            Query query = session.createQuery(delHql);
            query.executeUpdate();
//            session.delete("DynamicTemplate", dynamicTemplateMap);
            tx.commit();
            session.close();
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    public boolean deleteById(String tableName, String id) {
        try {
            Session session = this.getSessionFactory().openSession();
            Transaction tx = session.beginTransaction();
//            String delHql = String.format("delete %s a where a.id='%s'", tableName, id);
            Object object = session.get(tableName, id);
            if (object != null) {
                session.delete(object); //
            }
            tx.commit();
            session.close();
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    public boolean delete(Object obj) {
        try {
            Session session = this.getSessionFactory().openSession();
            Transaction tx = session.beginTransaction();
            session.delete(obj);
            tx.commit();
            session.close();
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    /**
     * 获取hbm所在路径
     *
     * @param entityName
     * @return
     */
    private String getHbmPath(String entityName) {
        try {
            File cfgFile = ResourceUtils.getFile("classpath:config/mapping/" + entityName + ".hbm.xml");
            if (!cfgFile.exists()) {
                cfgFile = ResourceUtils.getFile("classpath:config/mapping/DefaultTemplate.hbm.xml");
            }
            String hbmPath = cfgFile.getPath();  // "/Users/ziqilv/大地吉信/项目/瓦屋山/source/PatrolService/build/resources/main/config/mapping/";
            return hbmPath;
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 获取对象根据实体名称
     *
     * @param entityName
     * @return
     */
    public String getByEntity(String entityName) {
        String path = this.getHbmPath(entityName);
        if (path == null) {
            return null;
        }
        Session session = null;
        try {
            session = this.getSessionFactory().openSession();
            //s.get(entityName, new Integer(1400));
            String hql = "select count(*) from " + entityName;
            //List<Object> objectList = session.createQuery(hql).list();
            //session.close();
            //if (objectList != null) {
            //    Integer value = Integer.parseInt("0" + objectList.get(0).toString());
            //    if (value <= 0) {
            //        return null;
            //    }
            //    return "";
            //}
            int count = ((Number) session.createQuery(hql).uniqueResult()).intValue();
            session.close();
            if (count <= 0) {
                return null;
            } else {
                return "";
            }
        } catch (Exception ex) {
            if (session != null) {
                session.close();
            }
            return null;
        }
    }

    /**
     * 添加hbm.xml资源文件
     */
    public String addResource() {
        if (this.configuration == null) {
            this.getSessionFactory();
        }
        File cfgFile = null;
        try {
            cfgFile = ResourceUtils.getFile("classpath:config/mapping/DefaultTemplate.hbm.xml");
            cfgFile = new File(cfgFile.getParent());
            File[] files = cfgFile.listFiles();
            if (files != null && files.length > 0) {
                for (int i = 0; i < files.length; i++) {
                    String name = files[i].getName();
                    if (name.contains("hbm.xml")) {
                        this.configuration.addResource("config/mapping/" + name);
                    }
                }
            }
            return cfgFile.getPath() + File.separator;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }


}
